package com.simple.relaxed.manager.impl;

import com.simple.relaxed.local.LocalLayout;
import com.simple.relaxed.manager.AbstractManager;
import ohos.agp.components.Component;
import ohos.app.Context;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * LocalLayout的管理着，它存放着所有可以使用的LocalLayout的对象
 */
public class LocalLayoutManager extends AbstractManager<Class<? extends LocalLayout>, LocalLayout> {

    private static LocalLayoutManager localLayoutManager = new LocalLayoutManager();

    private LocalLayoutManager() {
        super();
    }

    public static LocalLayoutManager getInstance() {
        if (localLayoutManager == null) {
            localLayoutManager = new LocalLayoutManager();
        }
        return localLayoutManager;
    }

    /**
     * 调用此方法，注册并且实例化LocalLayout对象。
     *
     * @param cls     LocalLayout的类对象
     * @param context 使用LocalLayout的上下文对象
     * @throws NoSuchMethodException     找不到LocalLayout对象中的参数仅为Context对象的构造方法，将抛出此异常
     * @throws IllegalAccessException    反射调用构造方法因为参数错误失败时，抛出此异常
     * @throws InvocationTargetException 反射调用LocalLayout构造方法失败时，抛出此异常
     * @throws InstantiationException    实例化LocalLayout对象失败时，抛出此异常
     */
    public void register(Class<? extends LocalLayout> cls, Context context) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Constructor<? extends LocalLayout> constructor = cls.getDeclaredConstructor(Context.class);
        LocalLayout localLayout = constructor.newInstance(context);
        register(cls, localLayout);
    }

    /**
     * 调用此方法获取指定LocalLayout的主布局
     *
     * @param cls     LocalLayout的类对象
     * @param context 使用LocalLayout的上下文对象
     * @return 返回LocalLayout的主布局对象
     * @throws InvocationTargetException 反射调用LocalLayout构造方法失败时，抛出此异常
     * @throws NoSuchMethodException     找不到LocalLayout对象中的参数仅为Context对象的构造方法，将抛出此异常
     * @throws InstantiationException    实例化LocalLayout对象失败时，抛出此异常
     * @throws IllegalAccessException    反射调用构造方法因为参数错误失败时，抛出此异常
     */
    public Component getComponent(Class<? extends LocalLayout> cls, Context context) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        LocalLayout localLayout = map.get(cls);
        if (localLayout == null) {
            register(cls, context);
            localLayout = map.get(cls);
        }
        return localLayout.getComponent();
    }
}
